﻿using Flow.Manage.Contracts;
using Framework.Code.FlowWork;
using Framework.Models;
using Framework.Models.Entities;
using Framework.Models.Request;
using Framework.Repository;
using Framework.Utility.Helper;
using Framework.Utility.ViewModels;
using Microsoft.EntityFrameworkCore;

namespace Flow.Manage.Service
{
    public class WorkFlowService : IWorkFlowContract
    {
        private readonly IFlowschemeRepository _flowschemeRepository;
        private readonly IFlowinstanceRepository _flowinstanceRepository;
        private readonly FlowCenter _flowCenter;

        public WorkFlowService(IFlowschemeRepository flowschemeRepository, IFlowinstanceRepository flowinstanceRepository, FlowCenter flowCenter)
        {
            _flowschemeRepository = flowschemeRepository;
            _flowinstanceRepository = flowinstanceRepository;
            _flowCenter = flowCenter;
        }

        #region Flowscheme

        public async Task<TData<List<Fw_Flowscheme>>> GetFlowschemeList()
        {
            TData<List<Fw_Flowscheme>> tData = new TData<List<Fw_Flowscheme>>();
            tData.data = await _flowschemeRepository.EntitiesAsNoTracking.ToListAsync();
            return tData;
        }

        /// <summary>
        /// 根据schemeId 获取 流程模板信息
        /// </summary>
        /// <param name="schemeId"></param>
        /// <returns></returns>
        public async Task<TData> GetFlowschemeById(string schemeId)
        {
            TData tData = new TData(ResultTag.success);
            tData.data = await _flowschemeRepository.GetByKeyAsync(schemeId);
            return tData;
        }

        public TData<Fw_Flowscheme> FindFlowschemeByCode(string code)
        {
            TData<Fw_Flowscheme> tData = new TData<Fw_Flowscheme>();
            tData.data = _flowschemeRepository.GetFirstOrDefault(u => u.SchemeCode == code);
            return tData;
        }

        public async Task<TData> AddFlowScheme(Fw_FlowschemeRequest param)
        {
            var flowScheme = param.MapTo<Fw_Flowscheme>();

            if (_flowschemeRepository.CheckExists(u => u.SchemeName == flowScheme.SchemeName))
            {
                throw new Exception("流程名称已经存在");
            }
            flowScheme.Id = SnowflakeId.Id;
            flowScheme.CreateTime = DateTime.Now;
            flowScheme.CreateBy = "system";
            var count = await _flowschemeRepository.InsertAsync(flowScheme);
            return count > 0 ? new TData(ResultTag.success) : new TData(ResultTag.fail);
        }

        public async Task<TData> UpdateFlowscheme(Fw_FlowschemeRequest flowScheme)
        {
            var model = await _flowschemeRepository.GetByKeyAsync(flowScheme.Id);
            if (model == null)
            {
                throw new Exception("流程不存在");
            }
            model.SchemeCode = flowScheme.SchemeCode;
            model.SchemeName = flowScheme.SchemeName;
            model.SchemeCanUser = flowScheme.SchemeCanUser;
            model.SchemeVersion = flowScheme.SchemeVersion;
            model.SchemeType = flowScheme.SchemeType;
            model.SchemeContent = flowScheme.SchemeContent;
            model.FrmContentData = flowScheme.FrmContentData;
            model.Description = flowScheme.Description;
            model.DeduplicationType = flowScheme.DeduplicationType;
            model.UpdateBy = "system";
            model.UpdateTime = DateTime.Now;
            int count = await _flowschemeRepository.UpdateAsync(model);
            return count > 0 ? new TData(ResultTag.success) : new TData(ResultTag.fail);
        }

        /// <summary>
        /// 删除流程模板
        /// </summary>
        /// <param name="schemeId">流程模板id</param>
        /// <returns></returns>
        public async Task<TData> DelFlowScheme(string schemeId)
        {
            var entity = await _flowschemeRepository.GetByKeyAsync(schemeId);
            entity.IsDisabled = true;
            entity.IsDeleted = true;
            entity.UpdateTime = DateTime.Now;
            entity.UpdateBy = "system";
            var count = _flowschemeRepository.Update(entity);
            return count > 0 ? new TData(ResultTag.success) : new TData(ResultTag.fail);
        }

        #endregion Flowscheme

        #region Flowinstance

        /// <summary>
        /// 注册审批流程
        /// </summary>
        /// <param name="model"></param>
        /// <param name="flowScheme"></param>
        /// <returns></returns>
        public TData RegisterFlow(RegisterFlow model, object obj)
        {
            return _flowCenter.onRegisterFlowinstance(model, obj);
        }

        /// <summary>
        /// 获取流程实例列表
        /// </summary>
        /// <returns></returns>
        public async Task<TData<object>> GetFlowinstanceList()
        {
            TData<object> tData = new TData<object>();
            tData.data = await _flowinstanceRepository.EntitiesAsNoTracking.ToArrayAsync();
            tData.total = await _flowinstanceRepository.EntitiesAsNoTracking.CountAsync();
            return tData;
        }

        /// <summary>
        /// 流程实例预览
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        public async Task<TData<object>> GetFlowinstancebyId(string Id)
        {
            TData<object> tData = new TData<object>();
            tData.data = await _flowCenter.GetApprovalNodeList(Id);
            return tData;
        }

        public TData AddFlowinstance(Fw_FlowinstanceRequest param)
        {
            return _flowCenter.onAddFlowinstance(param);
        }

        public TData UpdateFlowinstance(Fw_FlowinstanceRequest param)
        {
            return _flowCenter.onUpdateFlowinstance(param);
        }

        #endregion Flowinstance

        #region 审批操作

        /// <summary>
        /// 审批
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        public TData FlowApproval(ApprovalReqest param)
        {
            _flowCenter.onProcessApproval(param);
            return new TData(ResultTag.success);
        }

        /// <summary>
        /// 发起审批流程
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        public TData FlowStart(string instanceId)
        {
            _flowCenter.onProcessInstanceStart(instanceId);
            return new TData(ResultTag.success);
        }

        /// <summary>
        /// 召回审批流程
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        public TData FlowReCall(string instanceId)
        {
            _flowCenter.onProcessInstanceReCall(instanceId);
            return new TData(ResultTag.success);
        }

        #endregion 审批操作
    }
}